# -*- conding: utf-8 -*-
from tkinter import *
import tkinter.messagebox
from socket import *
from threading import Thread,Lock
import sys,re


result_list = []

class mythread(Thread):
    def __init__(self, fun, args):
        Thread.__init__(self)
        self.fun = fun
        self.args = args

    def run(self):
        self.fun(*self.args)

class Port_Scan():
    def __init__(self,init_window_name):
        self.init_window_name = init_window_name

    #设置窗口
    def set_init_window(self):
        #设置名称
        self.init_window_name.title('黑客入侵端口扫描')
        #设置窗体大小
        self.init_window_name.geometry('450x600+150+150')
        #设置图标
        self.init_window_name.iconbitmap('./bitbug_favicon.ico')
        # 设置输入框 Entry
        label = Label(self.init_window_name,text ="请输入目标IP:").pack(side=LEFT,fill=NONE,anchor=N)
        self.IP = Entry(self.init_window_name)
        self.IP.pack(side=LEFT,fill=NONE,anchor=N)
        #设置扫描按钮
        Button(self.init_window_name,text="开始扫描",anchor='c',command=self.Judgment_IP).pack(side=LEFT,fill=NONE,anchor=N)
        Label(self.init_window_name,text ="Power by Songothao").pack(side=BOTTOM,fill=NONE,anchor=S)
        # Scrollbar
        self.scr = Scrollbar(self.init_window_name)
        self.lb = Listbox(self.init_window_name)
        self.scr.config(command=self.lb.yview)
        self.lb.config(yscrollcommand=self.scr.set)
        # for i in range(20):
            # self.lb.insert(END, "第%s项" % i)
        self.lb.pack(side=LEFT, fill=Y)
        self.scr.pack(side=LEFT, fill=Y)


    def Judgment_IP(self):
        self.lb.delete(0,END)
        # 判断输入的IP格式是否正确（正则）
        reg = '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
        ip = re.match(reg,self.IP.get())
        if ip is not None:
            self.action(ip.group())
            for item in result_list:
                self.lb.insert("end",item)
            pass

        else:
            print("IP格式错误")
            tkinter.messagebox.showerror('错误', 'IP格式错误')

    def action(self,ip):
        def scan(h, p):
            global result_list
            try:
                tcpCliSock = socket(AF_INET, SOCK_STREAM)
                tcpCliSock.connect((host, p))
                if lock.acquire():
                    result_list.append(str(p) + "端口已打开 \n")
                    lock.release()
            except error:
                if lock.acquire():
                    result_list.append(str(p) + "端口未打开 \n")
                    lock.release()
            finally:
                tcpCliSock.close()
                del tcpCliSock

        lock = Lock()
        ports = [21,23,53,80,135,139,445,1433,1521,3306,3389,4899,5631,5900,8080]
        host = ip
        mt = []
        for p in ports:
            t = mythread(scan, (host, p))
            mt.append(t)
        for m in mt:
            m.start()
        for m in mt:
            m.join()

if __name__ == '__main__':
    init_window = Tk()
    scan = Port_Scan(init_window)
    scan.set_init_window()
    init_window.mainloop()